﻿using Authority.DataTransferObject.Subsystem;
using Authority.Doamin;
using Authority.Doamin.IRepository;
using Authority.EFRepositoryImpl;
using Authority.IServices;
using Authority.IServices.Model.Subsystem;
using AutoMapper;
using HelperFromTheSkeleton.Convert;
using HelperFromTheSkeleton.Enums;
using HelperFromTheSkeleton.ExtendMethod;
using HelperFromTheSkeleton.Model.PageModel;
using System.Linq.Expressions;

namespace Authority.ServiceImpl
{
    /// <summary>
    /// 子系统权限服务
    /// </summary>
    public class SubsystemServiceImpl: ISubsystemService
    {
        private readonly ISubsystemRepository  _subsystemRepository;
        private readonly IActionAuthorityRepository _actionAuthorityRepository;
        private readonly IMenuAuthorityRepository _menuAuthorityRepository;
        private readonly IRoutingAuthorityRepository _routingAuthorityRepository;
        private readonly IUnitWork _unitWork;
        private readonly IMapper _mapper;

        public SubsystemServiceImpl(IUnitWork unitWork, IMapper mapper, ISubsystemRepository  subsystemRepository, IActionAuthorityRepository actionAuthorityRepository, IMenuAuthorityRepository menuAuthorityRepository, IRoutingAuthorityRepository routingAuthorityRepository)
        {
            _subsystemRepository = subsystemRepository;
            _unitWork = unitWork;
            _mapper = mapper;
            _actionAuthorityRepository = actionAuthorityRepository;
            _menuAuthorityRepository = menuAuthorityRepository;
            _routingAuthorityRepository = routingAuthorityRepository;
        }

        /// <summary>
        /// 新增子系统
        /// </summary>
        /// <param name="model"></param>
        /// <exception cref="InvalidOperationException"></exception>
        public async Task AddAsync(AddSubsystemModel model)
        {
            if (string.IsNullOrEmpty(model.Code)) throw new InvalidOperationException("子系统Code不能为空");
            if (string.IsNullOrWhiteSpace(model.Name)) throw new InvalidOperationException("子系统名称不能为空");
            if (await _subsystemRepository.CountAsync(m => m.Name == model.Name || m.Code == model.Code) > 0) throw new InvalidOperationException("子系统内的子系统名称、编号不允许重复");
            Subsystem dbInfo = _mapper.Map<Subsystem>(model);
            _unitWork.Add(dbInfo);
            await _unitWork.CommitAsync();
        }
        
        /// <summary>
        /// 修改子系统
        /// </summary>
        /// <param name="model"></param>
        /// <exception cref="InvalidOperationException"></exception>
        public async Task EditAsync(EditSubsystemModel model)
        {
            if (string.IsNullOrEmpty(model.Code)) throw new InvalidOperationException("子系统Code不能为空");
            if (string.IsNullOrWhiteSpace(model.Name)) throw new InvalidOperationException("子系统名称不能为空");
            if (model.ID == Guid.Empty) throw new InvalidOperationException("ID不能为空");
            Subsystem dbInfo = await _subsystemRepository.FirstAsync(m => m.ID == model.ID) ?? throw new InvalidOperationException("找不到此子系统权限");
            if (await _subsystemRepository.CountAsync(m => (m.Name == model.Name || m.Code == model.Code) && m.ID != model.ID) > 0) throw new InvalidOperationException("子系统内的子系统名称、编号不允许重复");
            model.CopyProperty(dbInfo);
            _unitWork.Updata(dbInfo);
            await _unitWork.CommitAsync();
        }

        /// <summary>
        /// 删除子系统
        /// </summary>
        /// <param name="id"></param>
        /// <returns></returns>
        /// <exception cref="InvalidOperationException"></exception>
        public async Task DeleteAsync(Guid id)
        {
            Subsystem dbInfo = await _subsystemRepository.FirstAsync(m => m.ID == id) ?? throw new InvalidOperationException("找不到此子系统权限");
            if (await _actionAuthorityRepository.CountAsync(m => m.SubsystemID == id) > 0) throw new InvalidOperationException("有功能正在关联此子系统");
            if (await _menuAuthorityRepository.CountAsync(m => m.SubsystemID == id) > 0) throw new InvalidOperationException("有菜单正在关联此子系统");
            if (await _routingAuthorityRepository.CountAsync(m => m.SubsystemID == id) > 0) throw new InvalidOperationException("有路由正在关联此子系统");
            _unitWork.Delete(dbInfo);
            await _unitWork.CommitAsync();
        }

        /// <summary>
        /// 获取子系统
        /// </summary>
        /// <param name="id"></param>
        /// <returns></returns>
        /// <exception cref="InvalidOperationException"></exception>
        public async Task<List<SubsystemDTO>> GetAsync(List<Guid> id)
        {
            List<Subsystem> dbInfo = await _subsystemRepository.FindAsync(m => id.Contains(m.ID),null);
            var result  = _mapper.Map<List<SubsystemDTO>>(dbInfo);
            return result;
        }

        /// <summary>
        /// 查询子系统
        /// </summary>
        /// <param name="model"></param>
        /// <returns></returns>
        public async Task<(List<SubsystemListDTO>, PageResultModel)> QueryAsync(QuerySubsystemModel model)
        {
            Expression<Func<Subsystem, bool>> expression = m => true;
            if (!string.IsNullOrWhiteSpace(model.Name)) expression = expression.And(m => m.Name == model.Name);
            if (!string.IsNullOrWhiteSpace(model.Code)) expression = expression.And(m => m.Code == model.Code);
            (List<Subsystem> dbInfos, PageResultModel page) = await _subsystemRepository.PageFindAsync(model, expression, m => m.Name, OrderByEnum.Asc);
            var result = _mapper.Map<List<SubsystemListDTO>>(dbInfos);
            return(result, page);
        }

        /// <summary>
        /// 查询子系统
        /// </summary>
        /// <param name="model"></param>
        /// <returns></returns>
        public async Task<List<SubsystemListDTO>> GetAllSubsystemAsync()
        {
            Expression<Func<Subsystem, bool>> expression = m => true;
            var entitys = await _subsystemRepository.FindAsync(expression, m => m.Name, OrderByEnum.Asc);
            var result = _mapper.Map<List<SubsystemListDTO>>(entitys);
            return result;
        }

    }

}